/*************************************************************************
 > Filename   : analyze.c
 > Author     : oneface - one_face@sina.com
 > Company    : 一尊还酹江月
 > Time       : 2018-02-28 09:30:00
 ************************************************************************/

#include <stdio.h>
#include "analyze.h"

static int parse_wavheader(FILE *file,
			   struct riff_wave_header *riff_wave_header,
			   struct chunk_header *chunk_header,
			   struct chunk_fmt *chunk_fmt)
{
	int more_chunks = 1;

	fread(riff_wave_header, sizeof(*riff_wave_header), 1, file);
	if ((riff_wave_header->riff_id != ID_RIFF) ||
	    (riff_wave_header->wave_id != ID_WAVE)) {
		printf("Error: this is not a riff/wave file\n");
		fclose(file);
		return -1;
	}

	//Note: please, stop to think what`s the chunks ...
	do {
		fread(chunk_header, sizeof(*chunk_header), 1, file);

		switch (chunk_header->id) {
		case ID_FMT:
			fread(chunk_fmt, sizeof(*chunk_fmt), 1, file);
			/* If the format header is larger, skip the rest */
			if (chunk_header->sz > sizeof(*chunk_fmt))
				fseek(file, chunk_header->sz - sizeof(*chunk_fmt),
				      SEEK_CUR);
			break;
		case ID_DATA:
			/* Stop looking for chunks */
			more_chunks = 0;
			break;
		default:
			/* Unknown chunk, skip bytes */
			fseek(file, chunk_header->sz, SEEK_CUR);
		}
	} while (more_chunks);

	//printf("wav header parse over chunk_fmt.bits_per_sample=%u\n", chunk_fmt->bits_per_sample);
}

/*
ret:
0:success -1:check error

 */
static int check_ffffff(FILE *file, uint16_t bits)
{
	int ret = 0;
	uint32_t *sample_24;
	uint16_t *sample_16;
	char *buffer = NULL;

	buffer = (char *)malloc(sizeof(char)*bits/8);
	if (!buffer) {
		printf("buffer malloc failed\n");
		return -1;
	}
	while ((ret = fread(buffer, 1, sizeof(char)*bits/8, file)) > 0) {
		//printf("%x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]);
		if (bits == 32) {
			sample_24 = (uint32_t *)buffer;
			//printf("%04x\n", *sample_24);
			if (*sample_24 == 0xffffff00) {
				printf("24bits find 0xffffff00 bug\n");
				ret = -1;
				break;
			}
		} else if (bits == 16) {
			sample_16 = (uint16_t *)buffer;
			if (*sample_16 == 0xffff) {
				printf("16bits find 0xffff bug\n");
				ret = -1;
				break;
			}
		} else {
			printf("bits %u is invalid\n", bits);
			ret = -1;
			break;
		}
	}

	free(buffer);
	buffer = NULL;

	return ret;
}

static int analyze_capdata(unsigned int repeat)
{
	int i;
	int ret = -1;
	FILE *file;
	char wavfile[256];
	struct riff_wave_header riff_wave_header;
	struct chunk_header chunk_header;
	struct chunk_fmt chunk_fmt;
	uint32_t *per_sample, *data_tmp;

	//for open /sdcard/pcm-test/repeat_000x.wav
	for (i = 0; i < repeat; i++) {
		sprintf(wavfile, "%s/repeat_000%d.wav", PCM_TEST, i);
		file = fopen(wavfile, "rb");
		if (!file) {
			printf("Unable to open file '%s'\n", wavfile);
			return -1;
		}

		//check ff ff ff
		ret =
		    parse_wavheader(file, &riff_wave_header,
				    &chunk_header, &chunk_fmt);
		if (ret == -1) {
			return -1;
		}

		printf("bits =%u\n", chunk_fmt.bits_per_sample);
		ret = check_ffffff(file, chunk_fmt.bits_per_sample);
		fclose(file);
		if (ret == -1) {
			printf("The file '%s' has [ff bug] or no data\n", wavfile);
			return -1;
		}
		printf("The file '%s' is OK\n", wavfile);
	}

	return 0;
}

int main()
{
	int ret = -1;
	unsigned int repeat = 5;

	ret = analyze_capdata(repeat);
	if (ret == 0) {
		printf("analyze succeed\n");
	} else {
		printf("analyze failed\n");
	}

	return 0;
}
